/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide; import java.beans.*; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.IOException; import java.util.Enumeration; import org.openide.util.HelpCtx; /** This class represents an abstract subclass for services * (compilation, execution, debugging, etc.) that can be registered in * the system. * * @author Jaroslav Tulach */ public abstract class ServiceType extends Object implements java.io.Serializable { /** generated Serialized Version UID */ static final long serialVersionUID = -7573598174423654252L; /** Name of property for the name of the service type. */ public static final String PROP_NAME = "name"; // NOI18N /** name of the service type */ private String name; /** listeners support */ private transient PropertyChangeSupport supp; /** Default human-presentable name of the service type. * In the default implementation, taken from the bean descriptor. * @return initial value of the human-presentable name * @see FeatureDescriptor#getDisplayName */ protected String displayName () { try { return Introspector.getBeanInfo (getClass ()).getBeanDescriptor ().getDisplayName (); } catch (Exception e) { // Catching IntrospectionException, but also maybe NullPointerException...? if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N e.printStackTrace (); return getClass ().getName (); } } /** Set the name of the service type. * Usually it suffices to override {@link #displayName}, * or just to provide a {@link BeanDescriptor} for the class. * @param name the new human-presentable name */ public void setName (String name) { String old = this.name; this.name = name; if (supp != null) { supp.firePropertyChange (PROP_NAME, old, name); } } /** Get the name of the service type. * The default value is given by {@link #displayName}. * @return a human-presentable name for the service type */ public String getName () { return name == null ? displayName () : name; } /** Get context help for this executor type. * @return context help */ public abstract HelpCtx getHelpCtx (); /** Add a property change listener. * @param l the listener to add */ public final synchronized void addPropertyChangeListener (PropertyChangeListener l) { if (supp == null) supp = new PropertyChangeSupport (this); supp.addPropertyChangeListener (l); } /** Remove a property change listener. * @param l the listener to remove */ public final void removePropertyChangeListener (PropertyChangeListener l) { if (supp != null) supp.removePropertyChangeListener (l); } /** Fire information about change of a property in the executor. * @param name name of the property * @param o old value * @param n new value */ protected final void firePropertyChange (String name, Object o, Object n) { if (supp != null) { supp.firePropertyChange (name, o, n); } } /** The registry of all services. This class is provided by the implementation * of the IDE and should hold all of the services registered to the system. * <P> * This class can be serialized to securely save settings of all * services in the system. */ public static abstract class Registry implements java.io.Serializable { /** suid */ final static long serialVersionUID = 8721000770371416481L; /** Get all available services managed by the engine. * @return an enumeration of {@link ServiceType}s */ public abstract Enumeration services (); /** Get all available services that are subclass of given class * @param clazz the class that all services should be subclass of * @return an enumeration of {@link ServiceType}s that are subclasses of * given class */ public Enumeration services (final Class clazz) { return new org.openide.util.enum.FilterEnumeration (services ()) { public boolean accept (Object o) { return clazz.isInstance (o); } }; } /** Getter for list of all services types. * @return list of ServiceType */ public abstract java.util.List getServiceTypes (); /** Setter for list of services types. This allows to change * instaces of the objects but only of the types that are already registered * to the system by manifest sections. If instance of any other type * is in the arr list it is ignored. * * @param arr list of ServiceTypes */ public abstract void setServiceTypes (java.util.List arr); /** Find the * executor implemented as a given class, among the executors registered to the * execution engine. * <P> * This should be used during (de-)serialization * of the specific executor for a data object: only store its class name * and then try to find the executor implemented by that class later. * * @param clazz the class of the executor looked for * @return the desired executor or <code>null</code> if it does not exist */ public ServiceType find (Class clazz) { Enumeration en = services (); while (en.hasMoreElements ()) { Object o = en.nextElement (); if (o.getClass () == clazz) { return (ServiceType)o; } } return null; } /** Find the * executor with requested name, among the executors registered to the * execution engine. * <P> * This should be used during (de-)serialization * of the specific executor for a data object: only store its name * and then try to find the executor later. * * @param name (display) name of executor to find * @return the desired executor or <code>null</code> if it does not exist */ public ServiceType find (String name) { Enumeration en = services (); while (en.hasMoreElements ()) { ServiceType o = (ServiceType)en.nextElement (); if (name.equals (o.getName ())) { return o; } } return null; } } /** Handle for an executor. This is a serializable class that should be used * to store executors and to recreate them after deserialization. */ public static final class Handle extends Object implements java.io.Serializable { /** generated Serialized Version UID */ static final long serialVersionUID = 7233109534462148872L; /** name executor */ private String name; /** name of class of the executor */ private String className; /** kept ServiceType may be <tt>null</tt> after deserialization */ private transient ServiceType serviceType; /** Create a new handle for an service. * @param ex the service to store a handle for */ public Handle (ServiceType ex) { name = ex.getName (); className = ex.getClass ().getName (); serviceType = ex; } /** Find the service for this handle. * @return the reconstituted executor */ public ServiceType getServiceType () { if (serviceType == null) { // try to find the executor by name TopManager tm = TopManager.getDefault (); ServiceType.Registry r = tm.getServices (); serviceType = r.find (name); if (serviceType != null) { return serviceType; } // try to find it by class try { serviceType = r.find ( Class.forName (className, true, tm.systemClassLoader ()) ); } catch (ClassNotFoundException ex) { } } return serviceType; } /** Old compatibility version. */ private void readObject (ObjectInputStream ois) throws IOException, ClassNotFoundException { name = (String)ois.readObject (); className = (String)ois.readObject (); } /** Has also save the object. */ private void writeObject (ObjectOutputStream oos) throws IOException { oos.writeObject (name); oos.writeObject (className); } } } /* * Log * 8 Gandalf 1.7 1/13/00 Ian Formanek NOI18N * 7 Gandalf 1.6 12/21/99 Jaroslav Tulach suid * 6 Gandalf 1.5 12/21/99 Jaroslav Tulach serviceTypes r/w property * 5 Gandalf 1.4 11/3/99 Jesse Glick ServiceType.displayName * <- BeanDescriptor.displayName. * 4 Gandalf 1.3 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 3 Gandalf 1.2 10/1/99 Jesse Glick Cleanup of service type * name presentation. * 2 Gandalf 1.1 10/1/99 Ales Novak Handle keeps transient * reference to its ServiceType * 1 Gandalf 1.0 9/10/99 Jaroslav Tulach * $ */